
Enter_information proc far   
    ; 函数：录入数据  
    ; 参数：ds:si 录入数据的位置
    ; 返回值：将录入的数据写在ds:si位置上
    ; 输入：姓名(16字节)、学号(16字节)、16 次实验成绩(16字节)和一次课程设计成绩（1字节)


    push bp
    mov bp,sp
    push ax
    push bx
    push cx
    push dx
    push es
    push di

    push si
    push ds

; 输入姓名 最大16字节
re_Enter_name:
    dispmsg Enter_name
    mov ax,1002h    ; 接收最大16字节的字母字符串
    call far ptr Get_input
    cmp ax,0BADh
    jz re_Enter_name

    ;ss:[bp-10h] = ds
    ;ss:[bp-0Eh] = si



; 输入学号 最大16字节 存储形式为字符
re_Enter_ID:
    ; 先将输入放到缓存区，再转换为数值复制到data段
    dispmsg Enter_ID
    ; mov_dssi_to_cache_area

    ; es:di 指向data段位置
    mov ax,ss:[bp-10h]
    mov ds,ax
    mov si,ss:[bp-0Eh]
    add si,10h

    mov ax,0C01h    ; 接收最大16字节的数字字符串
    call far ptr Get_input
    cmp ax,0BADh
    jz re_Enter_ID   ;输入不符合要求，重新输入



    


;输入平时成绩  分16次输入，每次输入0~100之间的数字
Enter_usual_score:
    mov cx,10h

    xor dx,dx ;dx存放16次平时成绩的和
    push dx
    mov ax,ss:[bp-10h]
    mov es,ax
    mov di,ss:[bp-0Eh]
    add di,1Bh
    mov_dssi_to_cache_area



Enter_usual_score_cycle:
    clear_area_ds _3
    mov ax,11h
    sub ax,cx
    call far ptr display_ax_dec
    dispmsg Enter_score_

    mov ax,0301h ;接收最大3字节的数字字符串
    call far ptr Get_input
    cmp ax,0BADh
    jz Enter_usual_score_error


    mov ax,3h
    call far ptr Convert_str_to_value
    cmp bx,0BADh
    jz Enter_usual_score_error
    cmp ax,64h   ;输入的数字大于100时进行错误处理
    ja Enter_usual_score_error

    ; 写入
    add di,1h
    mov es:[di],al
    pop dx
    add dx,ax
    push dx
    ; 清理缓存区
    
    loop Enter_usual_score_cycle
    jmp Enter_usual_score_done

Enter_usual_score_error:
    dispmsg Enter_score_error
    dispmsg next_row
    jmp Enter_usual_score_cycle





Enter_usual_score_done:
    add si,012h

    ; push dx ;将16次分数的和放入栈中


    


Enter_course_design_score:
    mov ax,ss:[bp-10h]
    mov es,ax
    mov di,ss:[bp-0Eh]
    add di,2Dh

    mov ax,00h
    mov es:[di-1],al

    mov_dssi_to_cache_area
Enter_course_design_start:
    clear_area_ds _3

    dispmsg Enter_course_design_score_
    mov ax,0301h ;接收最大3字节的数字字符串
    call far ptr Get_input
    cmp ax,0BADh
    jz Enter_course_design_score_error

    mov ax,3h
    call far ptr Convert_str_to_value
    cmp bx,0BADh
    jz Enter_course_design_score_error
    cmp ax,64h   ;输入的数字大于100时进行错误处理
    ja Enter_course_design_score_error 

    mov es:[di],al
    push ax
    jmp Enter_course_design_score_done

Enter_course_design_score_error: 
    ; dispmsg Enter_course_design_error
    dispmsg next_row
    jmp Enter_course_design_start


Enter_course_design_score_done: 
    

Calculate_finial_score:
    pop bx   ; bx存放课程设计成绩
    pop ax   ; ax存放16次实验成绩之和
    ; call far ptr Calculate_finial_score

    ;finial_score = (ax * 4 + bx * 16 * 6) / 160
    
    mov cx,4h
    mul cx
    ; ax *= 4
    push ax

    ; ax = bx * 96
    mov cx,60h
    mov ax,bx
    mul cx

    pop bx
    add ax,bx

    xor dx,dx
    mov cx,0A0h
    div cx

    cmp dx,050h
    jb Calculate_finial_score_out
    add ax,1h   ;四舍五入
Calculate_finial_score_out:
    push ax
    mov ax,ss:[bp-10h]
    mov es,ax
    mov di,ss:[bp-0Eh]
    add di,2Fh
    pop ax
    mov es:[di],ax
    mov ax,00h
    mov es:[di-1],al

Enter_information_done:
    dispmsg finish
    dispmsg next_row
    pop ax
    mov ds,ax
    pop si

    pop di
    pop es
    pop dx
    pop cx
    pop bx
    pop ax
    pop bp

    retf

Enter_information endp



Enter_information_Top proc far
    ; 总学生成绩数量加1
    mov ax,ss:[bp+16h]
    inc ax
    mov ss:[bp+16h],ax
    dec ax

    ; 学生数量*2h,得到当前要写入数据的偏移地址要写入的偏移地址
    ; 学生数量*2h*18h，得到当前要写入数据的偏移地址

    mov bl,2h
    mul bl
    push ax
    mov bl,18h
    mul bl
    push ax
    ; 写入该数据的偏移地址到pointers块中

    mov ax,pointers
    mov ds,ax
    lea si,pointers_start

    mov bx,ss:[bp-6]
    mov ax,ss:[bp-8]
    mov ds:[si+bx],ax



    ; 调用Enter_information函数
    mov ax,data
    mov ds,ax
    lea si,data_start
    pop ax
    add si,ax
    call far ptr Enter_information


; 计算统计信息
Calculate_statistics:
    mov bx,2Fh
    mov ax,ds:[si+bx] ;取最终成绩到ax中
    push ax

statistics_max: 
    mov dx,ss:[bp+0Ch]
    cmp ax,dx    ;是否超过原最高分
    jna statistics_min

    mov ss:[bp+0Ch],ax
statistics_min:
    mov dx,ss:[bp+0Ah]
    cmp ax,dx    ;是否低于原最低分
    jnb statistics_90_to_100

    mov ss:[bp+0Ah],ax
statistics_90_to_100:
    cmp ax,5Ah      ;是否大于90分
    jb statistics_80_to_89
    mov bx,ss:[bp+8h]
    inc bx
    mov ss:[bp+8h],bx
    jmp Calculate_average

statistics_80_to_89:
    cmp ax,50h       ;是否大于80分
    jb statistics_60_to_79
    mov bx,ss:[bp+6h]
    inc bx
    mov ss:[bp+6h],bx
    jmp Calculate_average

statistics_60_to_79:
    cmp ax,3Ch       ;是否大于60分
    jb statistics_lower_than_60
    mov bx,ss:[bp+4h]
    inc bx
    mov ss:[bp+4h],bx
    jmp Calculate_average

statistics_lower_than_60:
    mov bx,ss:[bp+2h]
    inc bx
    mov ss:[bp+2h],bx







; 计算平均成绩
Calculate_average:
    mov ax,ss:[bp+10h]    ; 获取原总分数
    mov dx,ss:[bp+12h]    

    pop bx
    add ax,bx
    adc dx,0

    mov  ss:[bp+10h],ax    ;写入新总分数s
    mov  ss:[bp+12h],dx

    mov bx,ss:[bp+16h]
    div bx  ;总平均分 = 所有学生平均分相加 / 总人数

    mov ss:[bp+0Eh],ax




    add sp,2h
    retf
Enter_information_Top endp